
#pragma once
#include "pde_export.h"
#include <vector>
#include <memory>
#include <string>
#include "glm/vec2.hpp"

namespace  pde
{
	class pde_export DoseModel {
	public:
		static std::shared_ptr<DoseModel> New();
		DoseModel();
		~DoseModel();

		std::string to_bson();
		bool from_bson(const std::string& bson_str);

		SetGetMacro(double, energy);

	    SetGetMacro(std::vector<double>, depth);
		SetGetMacro(std::vector<double>, dose);

		SetGetMacro(glm::dvec2, r_sq);//spot size
		SetGetMacro(glm::dvec2, theta_sq);//angular spread
		SetGetMacro(glm::dvec2, r_theta);//divergence

		SetGetMacro(double, idd_scale_factor);// used for scale absolute dose, default value 1.0
		SetGetMacro(long long, ions_per_mu);

		SetGetMacro(std::string, spot_tune_id);
        SetGetMacro(double, bragg_peak_wel);
        SetGetMacro(double, energy_spread);

	};
	
	//------------------------------------------------------------------------

	class pde_export RangeShifter {
	public:
		RangeShifter();
		~RangeShifter();
		static std::shared_ptr<RangeShifter> New();

		std::string to_bson();
		bool from_bson(const std::string& bson_str);

		SetGetMacro(std::string, name);
		SetGetMacro(std::string, mount_pos); //PatientSide, SourceSide
		SetGetMacro(int, plate_count);
		SetGetMacro(std::string, material_name); //PMMA
		SetGetMacro(int, ct_hu);
		SetGetMacro(double, radiation_length);
		SetGetMacro(std::vector<double>, plate_thickness_list);
		SetGetMacro(std::vector<double>, plate_position_list);
		SetGetMacro(std::string, acc_code); 

	};

	//------------------------------------------------------------------------
	class pde_export Nozzle {
	public:
		Nozzle();
		~Nozzle();
		static std::shared_ptr<Nozzle> New();

		std::string to_bson();
		bool from_bson(const std::string& bson_str);

		bool to_file(const std::string& fn);
		bool from_file(const std::string& fn);

		std::shared_ptr<DoseModel> get_dose_model(double energy);

		SetGetMacro(std::string, name);
		SetGetMacro(std::string, type);
		SetGetMacro(std::vector<std::shared_ptr<DoseModel>>, dose_models);

		SetGetMacro(glm::dvec2, focal_length);// sad, x = 2879 mm, y = 2422 mm

		SetGetMacro(glm::dvec2, couch_yaw_range);
		SetGetMacro(glm::dvec2, couch_roll_range);
		SetGetMacro(glm::dvec2, couch_pitch_range);
		SetGetMacro(glm::dvec2, gantry_rot_range);

		SetGetMacro(glm::dvec2, snout_move_range);
		SetGetMacro(std::shared_ptr<RangeShifter>, range_shifter);

		SetGetMacro(double, min_spot_mu); // mu/fx
		SetGetMacro(double, max_spot_mu); // mu/fx

		SetGetMacro(int, max_spot_count_per_beam); 
		SetGetMacro(int, max_layer_count_per_beam); 

		SetGetMacro(double, snout_tip_distance);
		SetGetMacro(glm::dvec2, snout_inner_diameter);
		SetGetMacro(glm::dvec2, snout_outer_diameter);


	};
	//---------------------------------------------------------------------------
}
